<html>
<head>
<title>WebGL Aquarium Notes</title>
<style>
BODY {
  font-family: sans-serif;
}
PRE {
  background-color: #ccc;
  margin-left: 4em;
  margin-right: 4em;
}
TABLE TD {
  border: 1px solid black;
  padding: 0.5em;
  vertical-align: top;
}
OL>LI {
  margin-top: 1em;
}
</style>
</head>
<body>
<h1>The WebGL Aquarium</h1>
<h2>Controls</h2>
<ul>
  <li>Use the mouse to change various settings.</li>
  <li>Click the * to bring up more settings.</li>
  <li>Press SPACE to change the view.</li>
  <li>Press L for sharks with frikken lasers. Looks best from an outside view.</li>
</ul>
<h2>Options</h2>
<ul>
    <li>
        <h3>numFish</h3>
        <p>set the number of fish</p>
        <pre><a href="aquarium.html?numFish=1234">https://webglsamples.github.io/aquarium/aquarium.html?numFish=1234</a></pre>
    </li>
    <li>
        <h3>canvasWidth, canvasHeight</h3>
        <p>set the canvas size, default value: 1024 * 1024</p>
        <pre><a href="aquarium.html?canvasWidth=1920&canvasHeight=1080">https://webglsamples.github.io/aquarium/aquarium.html?canvasWidth=1920&canvasHeight=1080</a></pre>
    </li>
    <li>
        <h3>fillWindow</h3>
        <p>set the canvas size to always fit the window, default value: false</p>
        <pre><a href="aquarium.html?fitWindow=true">https://webglsamples.github.io/aquarium/aquarium.html?fitWindow=true</a></pre>
    </li>
</ul>
<h2>Running across multiple machines</h2>
<p>The Aquarium demo can by run synchronized across multiple machines.</p>

<iframe width="800" height="450" src="https://www.youtube.com/embed/64TcBiqmVko?rel=0" frameborder="0" allowfullscreen></iframe>

<p>To run it across multiple machines each machine must be running a browser that supports WebGL and WebSockets.
Chromium for example. Next, the clocks of the 5 machines must be in sync. Then start the server. <a href="../server/README.html">See here for instructions</a>. Finally run the Aquarium with a URL in the following format.</p>
<pre>http://address_of_server:port_of_server/aquarium/aquarium.html?settings={net:{sync:true,rotYMult:mult}}</pre>
<p>Where <i>address_of_server</i> is the domain name or ip address of the server, <i>port_of_server</i> is the port of the server, and <i>mult</i> is 0 for the center machine, positive for machines to the right of the server and negative for machines to the left.</p>
<p>In other words, if the server is "myserver.com" and your running on port 8080 and you had 5 machines, A, B, C, D, E in that order left to right and you wanted machine C to be the master the URLs would for each machine would be:</p>
<pre>
Machine A: http://&lt;ipaddressofserver&gt;.com:8080/aquarium/aquarium.html?settings={net:{sync:true,ui:false,slave:true,fovMult:1.0,rotYMult:-2}}
Machine B: http://&lt;ipaddressofserver&gt;.com:8080/aquarium/aquarium.html?settings={net:{sync:true,ui:false,slave:true,fovMult:1.0,rotYMult:-1}}
Machine C: http://&lt;ipaddressofserver&gt;.com:8080/aquarium/aquarium.html?settings={net:{sync:true,ui:true,slave:false,fovMult:1.0,rotYMult:0}}
Machine D: http://&lt;ipaddressofserver&gt;.com:8080/aquarium/aquarium.html?settings={net:{sync:true,ui:false,slave:true,fovMult:1.0,rotYMult:-1}}
Machine E: http://&lt;ipaddressofserver&gt;.com:8080/aquarium/aquarium.html?settings={net:{sync:true,ui:false,slave:true,fovMult:1.0,rotYMult:-2}}
</pre>
<p>At that point, settings changed on the master should be propagated to the slaves.</p>
<h3>Options:</h3>
<table>
<tr><td>ui:</td><td>boolean</td><td><p>Whether or not to display a user interface.</p></td></tr>
<tr><td>sync:</td><td>boolean</td><td><p>Whether or not to get settings from a server</p></td></tr>
<tr><td>slave:</td><td>boolean</td><td><p>Whether or not to send settings to the server. False = send</p></td></tr>
<tr><td>rotYMult:</td><td>number</td><td><p>The amount to multiply the field of view for each monitor. Assumes they are all the same size.</p></td></tr>
<tr><td>fovMult:</td><td>number</td><td><p>The amount to multiply the field of view offset for each monitor.</p><p>The system computes the field of view for the monitor and multiplies by both rotYMult and fovMult to compute how much to rotate the view for each monitor. Think of rotYMult as a per machine setting and fovMult as a global setting. Adjust fovMult to specify the gap between monitors. For example on the Liquid Galaxy in the video above the fovMult is 1.12</p></td></tr>
<tr><td>fovFudge:</td><td>number</td><td><p>The amount to multiply the global field of view all monitors.</p><p>This is to work around a large array of monitors as the field of view setting is currently for a single monitor. For example if you have 4 monitors across you probably want to set this to 0.25</p></td></tr>
<tr><td>offset:</td><td>array</td><td><p>The amount to offset the frustum. Used to make a large virtual monitor. Example: offset:[-1,0] would define a monitor 1 unit left of the center monitor.</p></td></tr>
<tr><td>offsetMult:</td><td>number</td><td><p>Amount to multiply the offset by. Think of offset as a per machine setting and offsetMult as a global setting.</p></tr>
</table>
<h3>Terse Setup</h3>
<p>These steps worked for me as of 2017/12/1</p>
<p>On macOS</p>
<ol>
<li>download the source</li>
<li>install node.js  from <a href="http://nodejs.org/">http://nodejs.org/</a><br/>
Mine was 8.9.1</li>
<li>
<li>cd to the server folder of the samples (ie, "cd webglsamples/server")</li>
<li>install node deps by typing "npm install"</li>
<li>type node server.js</li>
<li>Start Chrome or Firefox</li>
<li>Make the window horizontally about 1/2 the size of your monitor or less</li>

<li>Make a new tab. Pull it off the window so you now have 2 browser
windows and arrange the 2 windows (which would both be the same size now)
side by side</li>

<li>In the right window use this URL<br/>
<a href="http://localhost:8080/aquarium/aquarium.html?settings={net:{sync:true,ui:true,slave:false,fovMult:1.0,rotYMult:0}}">http://localhost:8080/aquarium/aquarium.html?settings={net:{sync:true,ui:true,slave:false,fovMult:1.0,rotYMult:0}}</a></li>

<li>In the left window use this URL<br/>
<a href="http://localhost:8080/aquarium/aquarium.html?settings={net:{sync:true,ui:false,slave:true,fovMult:1.0,rotYMult:-1}}">http://localhost:8080/aquarium/aquarium.html?settings={net:{sync:true,ui:false,slave:true,fovMult:1.0,rotYMult:-1}}</a></li>
</ol>

<p>It will take up a few seconds for them to sync I think but it was
working for me ;-)</p>

<p>To run it across machines, change "localhost" to the ip address of the
machine running node.js</p>

<p>Note: you might have to stop and start node.js which you can do by
pressing Ctrl+Break twice in it's window</p>
<h2>Implemenation Notes:</h2>
<p>The aquarium runs almost entirely based on a clock. That means the position of the camera and every fish will be the same across machines if their clocks are in sync. When in networked mode each machine keeps its clock in sync by periodically asking the server for the current time. Otherwise, using node.js and the websocket library the master sends a JSON string with any new settings to the server. The server then broadcasts those settings to each of the machines.</p>
</body>
</html>

